Ecology job cycles

By Irene Steves

Straight out of undergrad, I was ready for some outdoor science. I started off with a short semi-volunteer field position in the early fall, and then headed home to the parents to apply for more.

I applied and applied… Not. A. Peep!

Once January rolled around, job offers finally started rolling in. Turned out, I had been applying in the wrong season. Had I done some data-sleuthing, I would have realized that winter is slow season for field jobs. So, now that I’m armed with those very skills, I am curious to explore when different types of ecology positions are posted on ecolog.

Data prep

Let’s start by getting some data…

library(tidyverse)
library(lubridate)
library(knitr)

data <- read.csv("../data/ecolog_all.csv",
                 stringsAsFactors = FALSE)

Rather than doing something fancy to sort these posts, I used str_detect to check if the collection of terms that I associate with faculty/graduate positions or jobs appear in the subject. Here, I’ve written this into a function:

is_position <- function(subject){
    subject %>% 
        str_to_lower() %>% 
        str_detect("job|hiring|employment|position|research associate|position|scientist|ecologist|researcher|technician|lead|assistant|fellow|educator|specialist|manager|biologist|coordinator|director|reu|undergrad| ms |msc|m.sc|master|graduate|ms|phd|ph.d|doctoral|graduate|post doc|postdoc|postdoctoral|professor|faculty|tenure|lecturer|instructor|temporary|intern|volunteer")
}

Now let’s apply it to the data and also categorize the posts into more specific groups, as well:

data_cat <- data %>% 
    as_tibble() %>% 
    filter(is_position(subject), 
           year(date) != 2018) %>% 
    #filter out 2018 because we only have partial data
    
    mutate(month = month(date), #for counting purposes later
           subject_low = str_to_lower(subject), #for str_detect case sensitivity
           is_fieldwork = str_detect(subject_low, "field|seasonal"),
           is_gradschool = str_detect(subject_low, " ms |msc|master|phd|ph.d|doctoral|graduate"),
           is_faculty = str_detect(subject_low, "faculty|tenure|professor")) %>% 
    
    rowwise() %>% 
    mutate(is_other = ifelse(sum(is_fieldwork, is_gradschool, is_faculty) == 0,
                             TRUE, FALSE))

Fieldwork

Based on my experience, the number of field job postings seems to really ramp up starting in January, probably peak right before summer, and then probably start dipping again by August. Let’s see if I’m right:

data_cat %>% 
  filter(is_fieldwork == TRUE) %>%  
  group_by(month) %>% 
  summarize(count = n()) %>% 
  ggplot() +
  geom_col(aes(x = as.factor(month), y = count)) +
  xlab("Month") + ylab("Number of posts") +
  theme_bw()

Based on the plot, it looks like January to March are peak hiring months on eco-log! My intuition was not exactly on the ball, but close.

MS/PhD positions

I suspect I’ll see a peak in fall, when many prospective students are applying to American graduate programs, which typically have deadlines in Nov-January.

data_cat %>% 
    filter(is_gradschool == TRUE) %>%  
    group_by(month) %>% 
    summarize(count = n()) %>% 
    ggplot() +
    geom_col(aes(x = as.factor(month), y = count)) +
    xlab("Month") + ylab("Number of posts") +
    theme_bw()

Interestingly, I see two peaks–one around January, and another around October. Let’s take a deeper look into this pattern and see if it repeats itself year after year.

data_cat %>% 
    filter(is_gradschool == TRUE) %>%  
    mutate(year = year(date)) %>% 
    group_by(month, year) %>% 
    summarize(count = n()) %>% 
    ggplot(aes(x = as.factor(month), y = count)) +
    geom_boxplot() +
    xlab("Month") + ylab("Number of postings") +
    theme_bw()

The pattern is still vaguely suggestive, but not all that clear. If we look at the last five years, we see that posts about graduate programs in 2016 and 2017 peaked in November, which may explain my initial guess.

data_cat %>% 
    filter(is_gradschool == TRUE) %>% 
    mutate(year = year(date)) %>% 
    filter(year >= 2012) %>% 
    group_by(month, year) %>% 
    summarize(count = n()) %>% 
    ggplot(aes(x = month, y = count, color = as.factor(year))) +
    geom_point() +
    geom_line() +
    xlab("Month") + ylab("Number of postings") +
    theme_bw()

Professorships

I am totally not in tune with this one, but I’ll just guess that March is high season since I recently hea(rd about a tenure-track interview at UCSB. I imagine many schools would want to choose faculty members and get them settled in by August/September for the new school year.

data_cat %>% 
    filter(is_faculty == TRUE) %>% 
    group_by(month) %>% 
    summarize(count = n()) %>% 
    ggplot(aes(x = as.factor(month), y = count)) +
    geom_col() +
    xlab("Month") + ylab("Number of postings") +
    theme_bw()

Surprisingly, September through November are peak months! Let’s scroll through our data and make sure our filtering gets us reasonable results:

data_cat %>% 
    filter(is_faculty == TRUE) %>%   
    select(date, subject) %>% 
    head(10) %>% 
    kable()
date subject
2017-12-22 11 Assistant professor positions (Tenure-track) in Sustainability Science, Utrecht University (The Netherlands)
2017-12-23 Assistant Professor, Environmental Chemistry and Global Change
2017-12-28 Job: Asst. Professor, Aquaculture/Aquaponics, Georgia Southern University
2017-12-21 President’s Professorship in Quantitative Fisherie s and Ecosystems
2017-12-15 Assistant or Associate Professor, Hydrology
2017-12-13 Assistant Professor: Microbial Interactions
2017-12-15 Assistant/Associate Professor of Plant Biology
2017-12-18 Asst. Prof Chemistry - Tenure Track
2017-12-18 Christmas gift idea for Students / Postdocs - New Career possibilities! (also faculty / scientists looking for new research areas!)
2017-12-15 Deadline Approaching: Associate Professor of Coupled Natural and Human Systems Modeling

Bringing it together

data_cat %>% 
    group_by(month, is_fieldwork, is_gradschool, is_faculty) %>% 
    summarize(count = n()) %>% 
    rowwise() %>% 
    filter(sum(is_fieldwork, is_gradschool, is_faculty) == 1) %>% 
    #filter out values that belong to multiple categories (for simplicity's sake)
    gather(type, value, is_fieldwork:is_faculty) %>% 
    filter(value == TRUE) %>% 
    mutate(type = str_replace(type, "is_", "")) %>% 
    
    #now to plot...
    ggplot(aes(x = as.factor(month), y = count, fill = type)) +
    geom_col(position = "dodge") +
    xlab("Month") + ylab("Number of postings") +
    theme_bw()